21장 빌트인 객체


객체 크게 3개로 나눌 수 있음.

표준 빌트인 객체

Math, Reflect, JSON 제외한 표준 빌트인 객체는 생성자 함수 객체.
즉, Math,Reflect, JSON 은 정적 메서드만 제공, 나머지는 프로토타입 메서드정적 메서드 제공.
빌트인 객체로 생성한 프로토타입은 빌트인 객체의 프로토타입을 상속.

// String 생성자 함수에 의한 String 객체 생성
const strObj = new String('Lee'); // String {"Lee"}

// String 생성자 함수를 통해 생성한 strObj 객체의 프로토타입은 String.prototype이다.
console.log(Object.getPrototypeOf(strObj) === String.prototype); // true

빌트인 객체는 인스턴스 없이 정적으로 호출할 수 있는 정적 메서드, 인스턴스가 상속을 통해 사용할 수 있는 프로토타입 메서드를 제공한다.

// Number 생성자 함수에 의한 Number 객체 생성
const numObj = new Number(1.5); // Number {1.5}

// toFixed는 Number.prototype의 프로토타입 메서드다.
// Number.prototype.toFixed는 소수점 자리를 반올림하여 문자열로 반환한다.
console.log(numObj.toFixed()); // 2

// isInteger는 Number의 정적 메서드다.
// Number.isInteger는 인수가 정수(integer)인지 검사하여 그 결과를 Boolean으로 반환한다.
console.log(Number.isInteger(0.5)); // false

원시값과 래퍼 객체

문자열, 숫자, 불리언 등은 그냥 원시값을 선언하고 사용할 수 있는데 왜 원시값 생성자 함수가 존재하나?

const str = 'hello';

// 원시 타입인 문자열이 프로퍼티와 메서드를 갖고 있는 객체처럼 동작한다.
console.log(str.length); // 5
console.log(str.toUpperCase()); // HELLO

원시값은 객체가 아니라서 프로퍼티와 메서드를 가질 수 없는데, 마치 객체처럼 동작한다. 어떻게?
⇒ 원시값에 객체처럼 접근하면 JS 엔진이 일시적으로 객체로 변환 해줌. 이렇게 생성된 임시 객체를 래퍼 객체라고 한다. 접근이 끝난 뒤 다시 원시값으로 되돌림.

Untitled 21.png|Untitled 21.png

문자열이 래퍼객체인 String 인스턴스로 변환되고, 4장 변수#^da8fbc) 당함.

const str = 'hello';

str.name = 'Lee';
console.log(str.name); // undefined

console.log(typeof str, str); // string hello

str.name = ‘Lee’ 수행하는 당시에만 string 래퍼 객체가 존재하고 가비지 컬렉션 된다.

전역 객체

코드가 실행되기 이전 단계에 JS 엔진에 의해 어떤 객체보다도 먼저 생성되는 특수한 객체이며 어떤 객체에도 속하지 않는 최상위 객체이다.

전역객체 특징

Note

➕실행컨텍스트에서 배우겠지만, 전역 렉시컬 환경은 객체 환경레코드와, 선언적 환경 레코드를 가지고 객체환경레코드에 window 객체가 바인딩된다. 그리고 window 객체에 전역변수와 전역함수가 프로퍼티로 할당된다.
하지만 함수 렉시컬 환경은 함수 환경 레코드만 가지고 여기에 매개인수, arugments, 지역변수 등이 저장됨. 즉 전역환경과 다르게 프로퍼티로 저장되는게 아님.

빌트인 전역 프로퍼티

➕ Number.NaN 이 window 에서 상속받은 건가 확인해봤는데, 자체적으로 가지고 있었다.

➕ Number.Infinity도 있는지 궁금햇는데, +,- 나누어져서 있었다.

Number.hasOwnProperty('NaN'); //true

Number.POSITIVE_INFINITY //Infinity
Number.NEGATIVE_INFINITY //-Infinity

빌트인 전역 함수

eval

자바스크립트 코드를 문자열 인수로 전달받음. 전달받은 코드가 표현식이면 런타임에 평가해서 값을 생성하고, 표현식이 아닌 문이라면 코드를 런타임에 실행

// 표현식인 문
eval('1 + 2;'); // -> 3
// 표현식이 아닌 문
eval('var x = 5;'); // -> undefined

// eval 함수에 의해 런타임에 변수 선언문이 실행되어 x 변수가 선언되었다.
console.log(x); // 5

// 객체 리터럴은 반드시 괄호로 둘러싼다.
const o = eval('({ a: 1 })');
console.log(o); // {a: 1}

// 함수 리터럴은 반드시 괄호로 둘러싼다.
const f = eval('(function() { return 1; })');
console.log(f()); // 1

eval 함수는 기존의 스코프를 런타임에 동적으로 수정한다. 이미 그 위치에 존재하던 코드처럼 동작

const x = 1;

function foo() {
  // eval 함수는 런타임에 foo 함수의 스코프를 동적으로 수정한다.
  eval('var x = 2;');
  console.log(x); // 2
}

foo();
console.log(x); // 1

strict mode 에서는 자체적인 스코프를 생산함.
만약 eval 내 코드가 let, const 키워드 이용한 변수 선언문이면 암묵적으로 strictmode 적용

const x = 1;

function foo() {
  eval('var x = 2; console.log(x);'); // 2
  // let, const 키워드를 사용한 변수 선언문은 strict mode가 적용된다.
  eval('const x = 3; console.log(x);'); // 3
  console.log(x); // 2
}

foo();
console.log(x); // 1
eval 함수는 보안에 취약하고, 처리속도가 느림 ⇒ 사용금지해라

원시값 관련

infinite : 유한수 인지 검사해서 true, false 반환
isNaN : 전달받은 인수가 NaN 인지 검사해서 true,false 반환
parseFloat **:**문자열을 실수로 해석해서 반환
parseInt :문자열을 정수로 해석해서 반환.

encodeURI / decodeURI

encodeURI 는 URI 를 문자열로 전달받아서 인코딩함.
URI : 인터넷에 있는 자원을 나타내는 유일한 주소

URL 에 아스키 문자만 올 수 있어서 특수문자, 한글, 공백 등처럼 URL 에 올 수 없는 문자를 인코딩해줘야함. 예를 들면 Base64

decodeURI : 인코딩된 URI를 전달받아서 디코딩함.

// 완전한 URI
const uri = 'http://example.com?name=이웅모&job=programmer&teacher';

// encodeURI 함수는 완전한 URI를 전달받아 이스케이프 처리를 위해 인코딩한다.
const enc = encodeURI(uri);
console.log(enc);
// http://example.com?name=%EC%9D%B4%EC%9B%85%EB%AA%A8&job=programmer&teacher

// decodeURI 함수는 인코딩된 완전한 URI를 전달받아 이스케이프 처리 이전으로 디코딩한다.
const dec = decodeURI(enc);
console.log(dec);
// http://example.com?name=이웅모&job=programmer&teacher

➕ URI 구성요소를 인코딩하고 디코딩하는 encodeURIComponent / decodeURIComponent 도 있음

암묵적 전역

var x = 10; // 전역 변수

function foo () {
  // 선언하지 않은 식별자에 값을 할당
  y = 20; // window.y = 20;
}
foo();

// 선언하지 않은 식별자 y를 전역에서 참조할 수 있다.
console.log(x + y); // 30

선언하지 않은 식별자에 값을 할당하면 참조에러가 발생하는데, JS 엔진이 window.y=20 으로 해석하고 전역 객체에 프로퍼티로 동적 생성해버림.

전역변수 처럼 동작하지만, 전역 변수는 아니고 전역 객체의 프로퍼티이다. 그래서 호이스팅도 발생하지 않음.

reference